﻿using RSSReader.Repository;
using RSSReader.DAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RSSReader.Service
{
  public class RssService : IRssService
  {

    #region Generalities

    private IRssRepository _repository { get; set; }

    public RssService(IRssRepository repo)
    {
      _repository = repo;
    }

    #endregion

    #region User management

    public ApplicationUser GetUser(int id)
    {
      return this._repository.GetUser(id);
    }

    public ApplicationUser GetUser(string userName, string password)
    {
      return this._repository.GetUser(userName, password);
    }

    public int AddUser(ApplicationUser user)
    {
      this._repository.AddUser(user);
      this._repository.SaveChanges();
      //return user.Id; //id non int?
      return -1;
    }

    public void DeleteUser(int userId)
    {
      var User = this._repository.GetUser(userId);
      if (User != null)
      {
        this._repository.DeleteUser(User);
        this._repository.SaveChanges();
      }
    }

    #endregion

    #region Subscription management

    public IEnumerable<Source> GetSubscription(int userId)
    {
      var UserSubs = this._repository.GetSubscriptions(userId);

      return this._repository.GetSources(UserSubs.Select(s => s.SourceId));
    }

    public IEnumerable<Source> AddSubscription(IEnumerable<string> sourceLinks, int userId)
    {
      var ExistingSources = this._repository.GetSources(sourceLinks).ToList();

      var User = this._repository.GetUser(userId);

      foreach (var link in sourceLinks)
      {
        var Source = ExistingSources.Where(w => w.Url == link).FirstOrDefault();

        if (Source == null)
        {
          Source = this._repository.AddSource(link);
          ExistingSources.Add(Source);
        }
        Subscription Sub = new Subscription { Source = Source, User = User, IsSubscribe = true };
        this._repository.AddSubscription(Sub);
      }

      this._repository.SaveChanges();

      return ExistingSources;
    }

    public void DeactivateSubscriptions(IEnumerable<string> sourceLinks, int userId)
    {
      var ExistingSources = this._repository.GetSources(sourceLinks).ToList();

      var Subscriptions = this._repository.GetSubscriptions(ExistingSources.Select(s => /*s.Id*/1/*TO REMOVE BUT CAN COMPILE*/), userId);

      foreach (var sub in Subscriptions)
        sub.IsSubscribe = false;

      this._repository.SaveChanges();
    }

    #endregion

    #region Feeds management

    public void NewRead(IEnumerable<string> feeds, int userId)
    {
      var Articles = this._repository.GetArticles(feeds);
      var User = this._repository.GetUser(userId);

      foreach (var feed in feeds)
      {
        var Article = Articles.Where(w => w.Url == feed).FirstOrDefault();
        if (Article == null)
        {
          Article = new Article { Url = feed, SourceId = -1/*TO THINK ABOUT*/ };
          this._repository.AddArticle(Article);
        }
        UserArticle NewRead = new UserArticle { Article = Article, User = User };
        this._repository.AddUserArticle(NewRead);
      }

      this._repository.SaveChanges();
    }

    public Dictionary<string, UserArticle> GetArticlesUserInfo(IEnumerable<string> feeds, int userId)
    {
      Dictionary<string, UserArticle> Res = new Dictionary<string, UserArticle>();

      var Articles = this._repository.GetArticles(feeds);
      var UserArticles = this._repository.GetUserArticles(Articles.Select(s => s.Id), userId);

      var Kvps = (from art in Articles
                  from usrArt in UserArticles
                  where art.Id == usrArt.ArticleId
                  select new KeyValuePair<string, UserArticle>(art.Url, usrArt));

      Res = Kvps.ToDictionary(key => key.Key, val => val.Value);

      return Res;
    }

    public void AddFavorite(IEnumerable<string> feeds, int userId)
    {
      //var Articles = this._repository.GetArticles(feeds);

      //var UserArticles = this._repository.GetUserArticles(Articles.Select(s => s.Id), userId);
      //var User = this._repository.GetUser(userId);
      ////NEED TO FINISH
      //foreach (var feed in feeds)
      //{
      //  var Art = Articles.Where(w => w.Url == feed).FirstOrDefault();
      //  if (Art == null)
      //  {
      //    Art = new Article { };
      //    this._repository.AddArticle(Art);
      //  }
      //  var UserArt = UserArticles.Where(w => w.ArticleId == Art.Id).FirstOrDefault();
      //  if (UserArt == null)
      //  {
      //    UserArt = new UserArticle { Article = Art, User = User };
      //    this._repository.AddUserArticle(UserArt);
      //  }
      //  UserArt.IsFavorite = true;
      //}
      //this._repository.SaveChanges();
      this.ManageFavorite(feeds, userId, true);
    }

    public void RemoveFavorite(IEnumerable<string> feeds, int userId)
    {
      this.ManageFavorite(feeds, userId, false);
    }

    private void ManageFavorite(IEnumerable<string> feeds, int userId, bool favoriteStatus)
    {
      var Articles = this._repository.GetArticles(feeds);

      var UserArticles = this._repository.GetUserArticles(Articles.Select(s => s.Id), userId);
      var User = this._repository.GetUser(userId);
      //NEED TO FINISH
      foreach (var feed in feeds)
      {
        var Art = Articles.Where(w => w.Url == feed).FirstOrDefault();
        if (Art == null)
        {
          Art = new Article { };
          this._repository.AddArticle(Art);
        }
        var UserArt = UserArticles.Where(w => w.ArticleId == Art.Id).FirstOrDefault();
        if (UserArt == null)
        {
          UserArt = new UserArticle { Article = Art, User = User };
          this._repository.AddUserArticle(UserArt);
        }
        UserArt.IsFavorite = favoriteStatus;
      }
      this._repository.SaveChanges();
    }

    #endregion

  }
}
